home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 114_01.zip / ED3.BDS < prev    next >
Text File  |  1993-06-01  |  14KB  |  713 lines

  1. /*
  2.  * Screen editor:  command mode commands -- enhanced
  3.  *
  4.  * Source: ed3.bds
  5.  * Version: December 20, 1981.
  6.  * Transliteration of small-C version of September 5, 1981
  7.  *
  8.  */
  9.  
  10. /* define globals */
  11.  
  12. #include ed.h
  13. #include bdscio.h
  14. #include ed1.ccc
  15. #include edext.cc
  16.  
  17. /* data global to these routines */
  18.  
  19. /* comment out -----
  20. char filename [SYSFNMAX];
  21. ----- end comment out */
  22.  
  23.  
  24. /* append command.
  25.  * load a file into main buffer at current location.
  26.  * this command does NOT change the current file name.
  27.  */
  28.  
  29. append(args) char *args;
  30. {
  31. char buffer [MAXLEN];        /* disk line buffer */
  32. int file;
  33. int n;
  34. int topline;
  35. char locfn [SYSFNMAX];        /* local file name */
  36.     /* get file name which follows command */
  37.     if (name1(args,locfn) == ERR) {
  38.         return;
  39.     }
  40.     if (locfn [0] == EOS) {
  41.         message("no file argument");
  42.         return;
  43.     }
  44.     /* open the new file */
  45.     if ((file=sysopen(locfn,"r")) == ERR) {
  46.         message("file not found");
  47.         return;
  48.     }
  49.     /* read the file into the buffer */
  50.     while ((n=readline(file,buffer,MAXLEN)) >= 0) {
  51.         if (n > MAXLEN) {
  52.             message("line truncated");
  53.             n=MAXLEN;
  54.         }
  55.         if (bufins(buffer,n) == ERR) {
  56.             break;
  57.         }
  58.         if (bufdn() == ERR) {
  59.             break;
  60.         }
  61.     }
  62.     /* close the file */
  63.     sysclose(file);
  64.     /* redraw the screen so topline will be at top
  65.      * of the screen after command() does a CR/LF.
  66.      */
  67.     topline=max(1,bufln()-SCRNL2);
  68.     bufout(topline,2,SCRNL2);
  69.     bufgo(topline);
  70. }
  71.  
  72. /* global change command */
  73.  
  74. change(args) char *args;
  75. {
  76. char oldline [MAXLEN1];        /* reserve space for EOS */
  77. char newline [MAXLEN1];
  78. char oldpat [MAXLEN1];
  79. char newpat [MAXLEN1];
  80. int from, to, col, n, k;
  81.     if (get2args(args,&from,&to) == ERR) {
  82.         return;
  83.     }
  84.     /* get search and change masks into oldpat, newpat */
  85.     fmtsout("search mask ?  ",0);
  86.     getcmnd(oldpat,15);
  87.     fmtcrlf();
  88.     if (oldpat [0] == EOS) {
  89.         return;
  90.     }
  91.     pmtline();
  92.     fmtsout("change mask ?  ",0);
  93.     getcmnd(newpat,15);
  94.     fmtcrlf();
  95.     /* make substitution for lines between from, to */
  96.     while (from <= to) {
  97.         if (chkkey() == YES) {
  98.             break;
  99.         }
  100.         if (bufgo(from++) == ERR) {
  101.             break;
  102.         }
  103.         if (bufatbot() == YES) {
  104.             break;
  105.         }
  106.         n=bufgetln(oldline,MAXLEN);
  107.         n=min(n,MAXLEN);
  108.         oldline [n]=EOS;
  109.         /* '^' anchors search */
  110.         if (oldpat [0] == '^') {
  111.             if (amatch(oldline,oldpat+1,0) == YES) {
  112.                 k=replace(oldline,newline,
  113.                     oldpat+1,newpat,0);
  114.                 if (k == ERR) {
  115.                     return;
  116.                 }
  117.                 fmtcrlf();
  118.                 putdec(bufln(),5);
  119.                 fmtsout(newline,5);
  120.                 outdeol();
  121.                 bufrepl(newline,k);
  122.             }
  123.             continue;
  124.         }
  125.         /* search oldline for oldpat */
  126.         col=0;
  127.         while (col < n) {
  128.             if (amatch(oldline,oldpat,col++) == YES){
  129.                 k=replace(oldline,newline,
  130.                     oldpat,newpat,col-1);
  131.                 if (k == ERR) {
  132.                     return;
  133.                 }
  134.                 fmtcrlf();
  135.                 putdec(bufln(),5);
  136.                 fmtsout(newline,5);
  137.                 outdeol();
  138.                 bufrepl(newline,k);
  139.                 break;
  140.             }
  141.         }
  142.     }
  143.     fmtcrlf();
  144. }
  145.  
  146. /* clear main buffer and file name */
  147.  
  148. clear()
  149. {
  150.     /* make sure it is ok to clear buffer */
  151.     if (chkbuf() == YES) {
  152.         filename [0]=0;
  153.         pmtfile("");
  154.         outclr();
  155.         outxy(0,SCRNL1);
  156.         bufnew();
  157.         message("buffer cleared");
  158.     }
  159. }
  160.  
  161. /* multiple line delete command */
  162.  
  163. delete(args) char *args;
  164. {
  165. int from, to;
  166.     if (get2args(args,&from,&to) == ERR) {
  167.         return;
  168.     }
  169.     if (from > to) {
  170.         return;
  171.     }
  172.     /* go to first line to be deleted */
  173.     if (bufgo(from) == ERR) {
  174.         return;
  175.     }
  176.     /* delete all line between from and to */
  177.     if (bufdeln(to-from+1) == ERR) {
  178.         return;
  179.     }
  180.     /* redraw the screen */
  181.     bufout(bufln(),1,SCRNL1);
  182. }
  183.  
  184. /* search all lines below the current line for a pattern
  185.  * return -1 if pattern not found.
  186.  * otherwise, return column number of start of pattern.
  187.  */
  188.  
  189. find()
  190. {
  191.     return(search1(bufln()+1,HUGE,YES));
  192. }
  193.  
  194. /* list lines to list device */
  195.  
  196. list(args) char *args;
  197. {
  198. char linebuf [MAXLEN1];
  199. int n;
  200. int from, to, line, oldline;
  201.     /* save the buffer's current line */
  202.     oldline=bufln();
  203.     /* get starting, ending lines to print */
  204.     if (get2args(args,&from,&to) == ERR) {
  205.         return;
  206.     }
  207.     /* print lines one at a time to list device */
  208.     line=from;
  209.     while (line <= to) {
  210.         /* make sure prompt goes to console */
  211.         fmtassn(NO);
  212.         /* check for interrupt */
  213.         if (chkkey() == YES) {
  214.             break;
  215.         }
  216.         /* print line to list device */
  217.         fmtassn(YES);
  218.         if (bufgo(line++) != OK) {
  219.             break;
  220.         }
  221.         if (bufatbot()) {
  222.             break;
  223.         }
  224.         n=bufgetln(linebuf,MAXLEN1);
  225.         n=min(n,MAXLEN);
  226.         linebuf [n]=CR;
  227.         fmtsout(linebuf,0);
  228.         fmtcrlf();
  229.     }
  230.     /* redirect output to console */
  231.     fmtassn(NO);
  232.     /* restore cursor */
  233.     bufgo(oldline);
  234. }
  235.  
  236. /* load file into buffer */
  237.  
  238. load (args) char *args;
  239. {
  240. char buffer [MAXLEN];    /* disk line buffer */
  241. char locfn  [SYSFNMAX];  /* file name until we check it */
  242. int n;
  243. int file;
  244. int topline;
  245.     /* get filename following command */
  246.     if (name1(args,locfn) == ERR) {
  247.         return;
  248.     }
  249.     if (locfn [0] == EOS) {
  250.         message("no file argument");
  251.         return;
  252.     }
  253.     /* give user a chance to save the buffer */
  254.     if (chkbuf() == NO) {
  255.         return;
  256.     }
  257.     /* open the new file */
  258.     if ((file=sysopen(locfn,"r")) == ERR) {
  259.         message("file not found");
  260.         return;
  261.     }
  262.     /* update file name */
  263.     syscopfn(locfn, filename);
  264.     pmtfile(filename);
  265.     /* clear the buffer */
  266.     bufnew();
  267.     /* read the file into the buffer */
  268.     while ((n=readline(file,buffer,MAXLEN)) >= 0) {
  269.         if (n > MAXLEN) {
  270.             message("line truncated");
  271.             n=MAXLEN;
  272.         }
  273.         if (bufins(buffer,n) == ERR) {
  274.             break;
  275.         }
  276.         if (bufdn() == ERR) {
  277.             break;
  278.         }
  279.     }
  280.     /* close the file */
  281.     sysclose(file);
  282.     /* indicate that the buffer is fresh */
  283.     bufsaved();
  284.     /* set current line to line 1 */
  285.     bufgo(1);
  286.     /* redraw the screen so that topline will be
  287.      * on line 1 after command() does a CR/LF.
  288.      */
  289.     topline=max(1,bufln()-SCRNL2);
  290.     bufout(topline,2,SCRNL2);
  291.     bufgo(topline);
  292. }
  293.  
  294. /* change current file name */
  295.  
  296. name(args) char *args;
  297. {
  298.     name1(args,filename);
  299.     pmtfile(filename);
  300. }
  301.  
  302. /* check syntax of args.
  303.  * copy to filename.
  304.  * return OK if the name is valid.
  305.  */
  306.  
  307. name1(args,filename) char *args, *filename;
  308. {
  309.     /* skip command */
  310.     args=skiparg(args);
  311.     args=skipbl(args);
  312.     /* check file name syntax */
  313.     if (syschkfn(args) == ERR) {
  314.         return(ERR);
  315.     }
  316.     /* copy filename */
  317.     syscopfn(args,filename);
  318.     return(OK);
  319. }
  320.  
  321. /* save the buffer in an already existing file */
  322.  
  323. resave()
  324. {
  325. char linebuf [MAXLEN];
  326. int file, n, oldline;
  327.     /* make sure file has a name */
  328.     if (filename [0] == EOS) {
  329.         message("file not named");
  330.         return;
  331.     }
  332.     /* the file must exist for resave */
  333.     if ((file=sysopen(filename,"r")) == ERR) {
  334.         message("file not found");
  335.         return;
  336.     }
  337.     if (sysclose(file) == ERR) {
  338.         return;
  339.     }
  340.     /* open the file for writing */
  341.     if ((file=sysopen(filename,"w")) == ERR) {
  342.         return;
  343.     }
  344.     /* save the current position of file */
  345.     oldline=bufln();
  346.     /* write out the whole file */
  347.     if (bufgo(1) == ERR) {
  348.         sysclose(file);
  349.         return;
  350.     }
  351.     while (bufatbot() == NO) {
  352.         n=bufgetln(linebuf,MAXLEN);
  353.         n=min(n,MAXLEN);
  354.         if (pushline(file,linebuf,n) == ERR) {
  355.             break;
  356.         }
  357.         if (bufdn() == ERR) {
  358.             break;
  359.         }
  360.     }
  361.     /* indicate if all buffer was saved */
  362.     if (bufatbot()){
  363.         bufsaved();
  364.     }
  365.     /* close file and restore line number */
  366.     sysclose(file);
  367.     bufgo(oldline);
  368. }
  369.  
  370. /* save the buffer in a new file */
  371.  
  372. save()
  373. {
  374. char linebuf [MAXLEN];
  375. int file, n, oldline;
  376.     /* make sure the file is named */
  377.     if (filename [0] == EOS) {
  378.         message("file not named");
  379.         return;
  380.     }
  381.     /* file must NOT exist for save */
  382.     if ((file=sysopen(filename,"r")) != ERR) {
  383.         sysclose(file);
  384.         message("file exists");
  385.         return;
  386.     }
  387.     /* open file for writing */
  388.     if ((file=sysopen(filename,"w")) == ERR) {
  389.         return;
  390.     }
  391.     /* remember current line */
  392.     oldline=bufln();
  393.     /* write entire buffer to file */
  394.     if (bufgo(1) == ERR) {
  395.         sysclose(file);
  396.         return;
  397.     }
  398.     while (bufatbot() == NO) {
  399.         n=bufgetln(linebuf,MAXLEN);
  400.         n=min(n,MAXLEN);
  401.         if (pushline(file,linebuf,n) == ERR) {
  402.             break;
  403.         }
  404.         if (bufdn() == ERR) {
  405.             break;
  406.         }
  407.     }
  408.     /* indicate buffer saved if good write */
  409.     if (bufatbot()) {
  410.         bufsaved();
  411.     }
  412.     /* restore line and close file */
  413.     bufgo(oldline);
  414.     sysclose(file);
  415. }
  416.  
  417. /* global search command */
  418.  
  419. search(args) char *args;
  420. {
  421. int from, to;
  422.  
  423.     if (get2args(args,&from,&to) == ERR) {
  424.         return;
  425.     }
  426.     search1(from, to, NO);
  427. }
  428.  
  429. /* search lines for a pattern.
  430.  * if flag  ==  YES: stop at the first match.
  431.  *                 return -1 if no match.
  432.  *                 otherwise return column number of match.
  433.  * if flag  ==  NO:  print all matches found.
  434.  */
  435.  
  436. search1(from, to, flag) int from, to, flag;
  437. {
  438. char pat   [MAXLEN1];        /* reserve space for EOS */
  439. char line  [MAXLEN1];
  440. int col, n;
  441.     /* get search mask into pat */
  442.     fmtsout("search mask ?  ",0);
  443.     getcmnd(pat,15);
  444.     fmtcrlf();
  445.     if (pat [0] == EOS) {
  446.         return;
  447.     }
  448.     /* search all lines between from and to for pat */
  449.     while (from <= to) {
  450.         if (chkkey() == YES) {
  451.             break;
  452.         }
  453.         if (bufgo(from++) == ERR) {
  454.             break;
  455.         }
  456.         if (bufatbot() == YES) {
  457.             break;
  458.         }
  459.         n=bufgetln(line,MAXLEN);
  460.         n=min(n,MAXLEN);
  461.         line [n]=EOS;
  462.         /* ^ anchors search */
  463.         if (pat [0] == '^') {
  464.             if (amatch(line,pat+1,0) == YES) {
  465.                 if (flag == NO) {
  466.                     fmtcrlf();
  467.                     putdec(bufln(),5);
  468.                     fmtsout(line,5);
  469.                     outdeol();
  470.                 }
  471.                 else {
  472.                     return(0);
  473.                 }
  474.             }
  475.             continue;
  476.         }
  477.         /* search whole line for match */
  478.         col=0;
  479.         while (col < n) {
  480.             if (amatch(line,pat,col++) == YES) {
  481.                 if (flag == NO) {
  482.                     fmtcrlf();
  483.                     putdec(bufln(),5);
  484.                     fmtsout(line,5);
  485.                     outdeol();
  486.                     break;
  487.                 }
  488.                 else {
  489.                     return(col-1);
  490.                 }
  491.             }
  492.         }
  493.     }
  494.     /* all searching is finished */
  495.     if (flag == YES) {
  496.         return(-1);
  497.     }
  498.     else {
  499.         fmtcrlf();
  500.     }
  501. }
  502.  
  503. /* set tab stops for fmt routines */
  504.  
  505. tabs(args) char *args;
  506. {
  507. int n, junk;
  508.     if (get2args(args,&n,&junk) == ERR) {
  509.         return;
  510.     }
  511.     fmtset(n);
  512. }
  513.  
  514. /* return YES if buffer may be drastically changed */
  515.  
  516. chkbuf()
  517. {
  518.     if (bufchng() == NO) {
  519.         /* buffer not changed. no problem */
  520.         return(YES);
  521.     }
  522.     fmtsout("buffer not saved. proceed ?  ",0);
  523.     pmtline();
  524.     if (tolower(syscout(syscin())) != 'y') {
  525.         fmtcrlf();
  526.         message("cancelled");
  527.         return(NO);
  528.     }
  529.     else {
  530.         fmtcrlf();
  531.         return(YES);
  532.     }
  533. }
  534.  
  535. /* print message from a command */
  536.  
  537. message(s) char *s;
  538. {
  539.     fmtsout(s,0);
  540.     fmtcrlf();
  541. }
  542.  
  543. /* get two arguments the argument line args.
  544.  * no arguments imply 1 HUGE.
  545.  * one argument implies both args the same.
  546.  */
  547.  
  548. get2args(args,val1,val2) char *args; int *val1, *val2;
  549. {
  550.     /* skip over the command */
  551.     args=skiparg(args);
  552.     args=skipbl(args);
  553.     if (*args == EOS) {
  554.         *val1=1;
  555.         *val2=HUGE;
  556.         return(OK);
  557.     }
  558.     /* check first argument */
  559.     if (number(args,val1) == NO) {
  560.         message("bad argument");
  561.         return(ERR);
  562.     }
  563.     /* skip over first argument */
  564.     args=skiparg(args);
  565.     args=skipbl(args);
  566.     /* 1 arg: arg 2 is HUGE */
  567.     if (*args == EOS) {
  568.         *val2=HUGE;
  569.         return(OK);
  570.     }
  571.     /* check second argument */
  572.     if (number(args,val2) == NO) {
  573.         message("bad argument");
  574.         return(ERR);
  575.     }
  576.     else {
  577.         return(OK);
  578.     }
  579. }
  580.  
  581. /* skip over all except EOS, and blanks */
  582.  
  583. skiparg(args) char *args;
  584. {
  585.     while (*args != EOS && *args!=' ') {
  586.         args++;
  587.     }
  588.     return(args);
  589. }
  590.  
  591. /* skip over all blanks */
  592.  
  593. skipbl(args) char *args;
  594. {
  595.     while (*args == ' ') {
  596.         args++;
  597.     }
  598.     return(args);
  599. }
  600.  
  601. /* return YES if the user has pressed any key.
  602.  * blanks cause a transparent pause.
  603.  */
  604. chkkey()
  605. {
  606. int c;
  607.     c=syscstat();
  608.     if (c == 0) {
  609.         /* no character at keyboard */
  610.         return(NO);
  611.     }
  612.     else if (c == ' ') {
  613.         /* pause.  another blank ends pause */
  614.         pmtline();
  615.         if (syscin() == ' ') {
  616.             return(NO);
  617.         }
  618.     }
  619.     /* we got a nonblank character */
  620.     return(YES);
  621. }
  622.  
  623. /* anchored search for pattern in text line at column col.
  624.  * return YES if the pattern starts at col.
  625.  */
  626.  
  627. amatch(line,pat,col) char *line, *pat; int col;
  628. {
  629. int k;
  630.     k=0;
  631.     while (pat [k] != EOS) {
  632.         if (pat [k] == line[col]) {
  633.             k++;
  634.             col++;
  635.         }
  636.         else if (pat [k] == '?' && line[col] != EOS) {
  637.             /* question mark matches any char */
  638.             k++;
  639.             col++;
  640.         }
  641.         else {
  642.             return(NO);
  643.         }
  644.     }
  645.     /* the entire pattern matches */
  646.     return(YES);
  647. }
  648.  
  649. /* replace oldpat in oldline by newpat starting at col.
  650.  * put result in newline.
  651.  * return number of characters in newline.
  652.  */
  653.  
  654. replace(oldline,newline,oldpat,newpat,col)
  655. char *oldline, *newline, *oldpat, *newpat; int col;
  656. {
  657. int k;
  658. char *tail, *pat;
  659.     /* copy oldline preceding col to newline */
  660.     k=0;
  661.     while (k < col) {
  662.         newline [k++]=*oldline++;
  663.     }
  664.     /* remember where end of oldpat in oldline is */
  665.     tail=oldline;
  666.     pat=oldpat;
  667.     while (*pat++ != EOS) {
  668.         tail++;
  669.     }
  670.     /* copy newpat to newline.
  671.      * use oldline and oldpat to resolve question marks
  672.      * in newpat.
  673.      */
  674.     while (*newpat != EOS) {
  675.         if (k > MAXLEN-1) {
  676.             message("new line too long");
  677.             return(ERR);
  678.         }
  679.         if (*newpat != '?') {
  680.             /* copy newpat to newline */
  681.             newline [k++]=*newpat++;
  682.             continue;
  683.         }
  684.         /* scan for '?' in oldpat */
  685.         while (*oldpat != '?') {
  686.             if (*oldpat == EOS) {
  687.                 message(
  688.                 "too many ?'s in change mask"
  689.                 );
  690.                 return(ERR);
  691.             }
  692.             oldpat++;
  693.             oldline++;
  694.         }
  695.         /* copy char from oldline to newline */
  696.         newline [k++]=*oldline++;
  697.         oldpat++;
  698.         newpat++;
  699.     }
  700.     /* copy oldline after oldpat to newline */
  701.     while (*tail != EOS) {
  702.         if (k >= MAXLEN-1) {
  703.             message("new line too long");
  704.             return(ERR);
  705.         }
  706.         newline [k++]=*tail++;
  707.     }
  708.     newline [k]=EOS;
  709.     return(k);
  710. }
  711.  
  712. */
  713.     k=0;